package com.tgo.android.views;

import java.util.ArrayList;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.SharedPreferences;
import android.location.Geocoder;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.InfoWindowAdapter;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.tgo.android.R;
import com.tgo.android.common.entities.Offer;
import com.tgo.android.common.utilities.ExampleService;
import com.tgo.android.common.utilities.LocationUtils;

public class MainActivity extends FragmentActivity implements
LocationListener,
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener
{
	//region hola
	static final LatLng HAMBURG = new LatLng(10.472731,-66.960769);
	static final LatLng KIEL = new LatLng(10.471581,-66.961488);

	private LocationRequest _locationRequest;
	private LocationClient _locationClient;

	private Location _location;
	
	private Intent _service;

	SharedPreferences _sharedPrefs;// Handle to SharedPreferences for this app
	SharedPreferences.Editor _sharedPrefsEditor;// Handle to a SharedPreferences editor

	private boolean _updatesRequested;
	private GoogleMap _map;
	
	private TextView _storeName;
	private TextView _deal;
    private TextView _directionFromGPS;
    private TextView _directionFromCustomer;
	

	/*
	 * Initialize the Activity
	 */
	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initializeComponents();
		startService(_service);
	}

	/*
	 * Called when the Activity is no longer visible at all.
	 * Stop updates and disconnect.
	 */
	@Override
	public void onStop()
	{
		if (_locationClient.isConnected())
			stopPeriodicUpdates();
		_locationClient.disconnect();

		super.onStop();
	}


	/*
	 * Called when the Activity is going into the background.
	 * Parts of the UI may be visible, but the Activity is inactive.
	 */
	@Override
	public void onPause()
	{
		// Save the current setting for updates
		_sharedPrefsEditor.putBoolean(LocationUtils.KEY_UPDATES_REQUESTED, _updatesRequested);
		_sharedPrefsEditor.commit();

		super.onPause();
	}

	/*
	 * Called when the Activity is restarted, even before it becomes visible.
	 */
	@Override
	public void onStart()
	{
		super.onStart();
		_locationClient.connect();

	}

	/*
	 * Called when the system detects that this Activity is now visible.
	 */
	@Override
	public void onResume()
	{
		super.onResume();

		// If the app already has a setting for getting location updates, get it
		if (_sharedPrefs.contains(LocationUtils.KEY_UPDATES_REQUESTED))
			_updatesRequested = _sharedPrefs.getBoolean(LocationUtils.KEY_UPDATES_REQUESTED, false);
		else // Otherwise, turn off location updates until requested
		{
			_sharedPrefsEditor.putBoolean(LocationUtils.KEY_UPDATES_REQUESTED, false);
			_sharedPrefsEditor.commit();
		}
	}

	/*
	 * Handle results returned to this Activity by other Activities started with
	 * startActivityForResult(). In particular, the method onConnectionFailed() in
	 * LocationUpdateRemover and LocationUpdateRequester may call startResolutionForResult() to
	 * start an Activity that handles Google Play services problems. The result of this
	 * call returns here, to onActivityResult.
	 */
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent intent)
	{
		// Choose what to do based on the request code
		switch (requestCode) {

		// If the request code matches the code sent in onConnectionFailed
		case LocationUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST :

			switch (resultCode) {
			// If Google Play services resolved the problem
			case Activity.RESULT_OK:

				// Log the result
				//				Log.d(LocationUtils.APPTAG, getString(R.string.resolved));
				//
				//				// Display the result
				//				mConnectionState.setText(R.string.connected);
				//				mConnectionStatus.setText(R.string.resolved);
				break;

				// If any other result was returned by Google Play services
			default:
				// Log the result
				//				Log.d(LocationUtils.APPTAG, getString(R.string.no_resolution));
				//
				//				// Display the result
				//				mConnectionState.setText(R.string.disconnected);
				//				mConnectionStatus.setText(R.string.no_resolution);

				break;
			}

			// If any other request code was received
		default:
			// Report that this Activity received an unknown requestCode
			//			Log.d(LocationUtils.APPTAG,
			//					getString(R.string.unknown_activity_request_code, requestCode));

			break;
		}
	}

	/**
	 * Verify that Google Play services is available before making a request.
	 *
	 * @return true if Google Play services is available, otherwise false
	 */
	private boolean servicesConnected()
	{
		boolean isConnected = false;
		// Check that Google Play services is available
		int resultCode =
				GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);

		// If Google Play services is available
		if (ConnectionResult.SUCCESS == resultCode)
			isConnected = true;
		else // Google Play services was not available for some reason
		{
			// Display an error dialog
			Dialog dialog = GooglePlayServicesUtil.getErrorDialog(resultCode, this, 0);
			if (dialog != null)
			{
				ErrorDialogFragment errorFragment = new ErrorDialogFragment();
				errorFragment.setDialog(dialog);
				errorFragment.show(getSupportFragmentManager(), LocationUtils.APPTAG);
			}
		}
		return isConnected;
	}


	/**
	 * Invoked by the "Get Address" button.
	 * Get the address of the current location, using reverse geocoding. This only works if
	 * a geocoding service is available.
	 *
	 * @param v The view object associated with this method, in this case a Button.
	 */
	// For Eclipse with ADT, suppress warnings about Geocoder.isPresent()
	@SuppressLint("NewApi")
	public void getAddress(View v) {

		// In Gingerbread and later, use Geocoder.isPresent() to see if a geocoder is available.
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD && !Geocoder.isPresent()) {
			// No geocoder is present. Issue an error message
			Toast.makeText(this, "No geocoder avaiable", Toast.LENGTH_LONG).show();
			return;
		}

		if (servicesConnected()) {

			// Get the current location
			Location currentLocation = _locationClient.getLastLocation();

			// Turn the indefinite activity indicator on
			//			mActivityIndicator.setVisibility(View.VISIBLE);

			// Start the background task
			//			(new MainActivity.GetAddressTask(this)).execute(currentLocation);
		}
	}

	//jcError
	/**
	 * Invoked by the "Start Updates" button
	 * Sends a request to start location updates
	 *
	 * @param v The view object associated with this method, in this case a Button.
	 */
	public void startUpdates(View v)
	{
			startPeriodicUpdates();
		
	}

	//jcError
	/**
	 * Invoked by the "Stop Updates" button
	 * Sends a request to remove location updates
	 * request them.
	 *
	 * @param v The view object associated with this method, in this case a Button.
	 */
	public void stopUpdates(View v)
	{
			stopPeriodicUpdates();
	}

	/*
	 * Called by Location Services when the request to connect the
	 * client finishes successfully. At this point, you can
	 * request the current location or start periodic updates
	 */
	@Override
	public void onConnected(Bundle bundle)
	{
		if (servicesConnected())
			initializeMapComponents();

	}

	/*
	 * Called by Location Services if the connection to the
	 * location client drops because of an error.
	 */
	@Override
	public void onDisconnected() {
		//		mConnectionStatus.setText(R.string.disconnected);
	}

	/*
	 * Called by Location Services if the attempt to
	 * Location Services fails.
	 */
	@Override
	public void onConnectionFailed(ConnectionResult connectionResult) {

		/*
		 * Google Play services can resolve some errors it detects.
		 * If the error has a resolution, try sending an Intent to
		 * start a Google Play services activity that can resolve
		 * error.
		 */
		if (connectionResult.hasResolution()) {
			try {

				// Start an Activity that tries to resolve the error
				connectionResult.startResolutionForResult(
						this,
						LocationUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST);

				/*
				 * Thrown if Google Play services canceled the original
				 * PendingIntent
				 */

			} catch (IntentSender.SendIntentException e) {

				// Log the error
				e.printStackTrace();
			}
		} else {

			// If no resolution is available, display a dialog to the user with the error.
			showErrorDialog(connectionResult.getErrorCode());
		}
	}

	/**
	 * Report location updates to the UI.
	 *
	 * @param location The updated location.
	 */
	@Override
	public void onLocationChanged(Location location) {

		// Report to the UI that the location was updated
		//		mConnectionStatus.setText(R.string.location_updated);

		// In the UI, set the latitude and longitude to the value received
		//		mLatLng.setText(LocationUtils.getLatLng(this, location));
	}

	/**
	 * In response to a request to start updates, send a request
	 * to Location Services
	 */
	private void startPeriodicUpdates() {

		_updatesRequested = true;

		if (servicesConnected())
			_locationClient.requestLocationUpdates(_locationRequest, this);
		
		//		mConnectionState.setText(R.string.location_requested);
	}

	/**
	 * In response to a request to stop updates, send a request to
	 * Location Services
	 */
	private void stopPeriodicUpdates() 
	{
		_updatesRequested = false;

		if (servicesConnected()) 
			_locationClient.removeLocationUpdates(this);
		//		mConnectionState.setText(R.string.location_updates_stopped);
	}


	//	}

	/**
	 * Show a dialog returned by Google Play services for the
	 * connection error code
	 *
	 * @param errorCode An error code returned from onConnectionFailed
	 */
	private void showErrorDialog(int errorCode) {

		// Get the error dialog from Google Play services
		Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
				errorCode,
				this,
				LocationUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST);

		// If Google Play services can provide an error dialog
		if (errorDialog != null)
		{
			ErrorDialogFragment errorFragment = new ErrorDialogFragment();// Create a new DialogFragment in which to show the error dialog	
			errorFragment.setDialog(errorDialog);// Set the dialog in the DialogFragment
			errorFragment.show(getSupportFragmentManager(), LocationUtils.APPTAG);// Show the error dialog in the DialogFragment
		}
	}

	/**
	 * Define a DialogFragment to display the error dialog generated in
	 * showErrorDialog.
	 */
	public static class ErrorDialogFragment extends DialogFragment {

		// Global field to contain the error dialog
		private Dialog mDialog;

		/**
		 * Default constructor. Sets the dialog field to null
		 */
		public ErrorDialogFragment() {
			super();
			mDialog = null;
		}

		/**
		 * Set the dialog to display
		 *
		 * @param dialog An error dialog
		 */
		public void setDialog(Dialog dialog) {
			mDialog = dialog;
		}

		/*
		 * This method must return a Dialog to the DialogFragment.
		 */
		@Override
		public Dialog onCreateDialog(Bundle savedInstanceState) {
			return mDialog;
		}
	}

	/**
	 * Initialize the general attibutes of the class
	 */
	private void initializeComponents()
	{
		_service = new Intent(this, ExampleService.class);
		_locationRequest = LocationRequest.create();
		_locationRequest.setInterval(LocationUtils.UPDATE_INTERVAL_IN_MILLISECONDS);
		_locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
		_locationRequest.setFastestInterval(LocationUtils.FAST_INTERVAL_CEILING_IN_MILLISECONDS);

		_updatesRequested = false;

		_sharedPrefs = getSharedPreferences(LocationUtils.SHARED_PREFERENCES, Context.MODE_PRIVATE);
		_sharedPrefsEditor = _sharedPrefs.edit();

		_locationClient = new LocationClient(this, this, this);


	}

	private void initializeMapComponents()
	{
		_storeName = (TextView) findViewById(R.id.infoWindowTvStoreName);
		_deal = (TextView) findViewById(R.id.infoWindowTvDeal);
		_directionFromGPS = (TextView) findViewById(R.id.infoWindowTvDrirectionFromGPS);
		_directionFromCustomer = (TextView) findViewById(R.id.infoWindowTvDrirectionFromCustomer);
		_map = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
		
		_map.setMyLocationEnabled(true);
		_location = _locationClient.getLastLocation();
		_map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(_location.getLatitude(), _location.getLongitude()), 60));
		//startPeriodicUpdates();
		
		Marker hamburg = _map.addMarker(new MarkerOptions().position(HAMBURG)
		        .title("Hamburg")
		        .snippet("hola"));
//		    Marker kiel = _map.addMarker(new MarkerOptions()
//		        .position(KIEL)
//		        .title("Kiel")
//		        .snippet("Kiel is cool")
//		        .icon(BitmapDescriptorFactory
//		            .fromResource(R.drawable.ic_launcher)));

		    // Move the camera instantly to hamburg with a zoom of 15.
		    //_map.moveCamera(CameraUpdateFactory.newLatLngZoom(HAMBURG, 15));

		    // Zoom in, animating the camera.
		    //_map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
		    
		    
		    
		    
		    
		    
		    
		    
		 // Setting a custom info window adapter for the google map
	        _map.setInfoWindowAdapter(new InfoWindowAdapter() {
	 
	            // Use default InfoWindow frame
	            @Override
	            public View getInfoWindow(Marker arg0) {
	                return null;
	            }
	 
	            // Defines the contents of the InfoWindow
	            @Override
	            public View getInfoContents(Marker myMarker)
	            {
	            	Offer offer = searchMarkerInfo(myMarker.getPosition());
	            	View customInfoWindow = getLayoutInflater().inflate(R.layout.tgo_custom_infowindow, null);
	            	_storeName.setText(offer.getTitle());
	            	_deal.setText(offer.getDescription());
	                return customInfoWindow;	 
	            }
	        });
	        
	        Marker jc = _map.addMarker(new MarkerOptions()
	        .position(KIEL)
	        .icon(BitmapDescriptorFactory
	            .fromResource(R.drawable.ic_on_fire)));
		
	        //jc.showInfoWindow();
	}


	private Offer searchMarkerInfo(LatLng position)
	{
		Offer result = null;
		boolean isFound = false;
		ArrayList<Offer> list =  new ArrayList<Offer>();
		for (int i = 0; i < list.size() && !isFound; i++) {
			if (list.get(i).getLocation().equals(position))
			{
				result = list.get(i);
				isFound = true;
			}
		}
		return result;
	}
}
